import java.util.LinkedList;
import java.util.Queue;
import java.util.Vector;


public class DFA {
	private Vector<SetState> states;
	private SetState initialState;
	public static State  automataFinalState;
	private AutomataVisualizer visualizer;
	public DFA(Automata automata)
	{
		Vector<State> set = new Vector<State>();
		states = new Vector<SetState>();
		automataFinalState =automata.getFinalState();
		initialState = new SetState(automata.getInitialState().statesReachable(set));
		states.add(initialState);
		
		for(int i = 0; i<states.size();i++)
		{
			SetState tmp_state = states.get(i);
			Vector<String> transitions = tmp_state.listTransitions();
			
			for(int j = 0 ; j<transitions.size(); j++)
			{
				set = new Vector<State>();
				set =  tmp_state.setStateReachable(transitions.get(j));
				
				SetState newSetState = new SetState(set);
				if(states.contains(newSetState))
				{
					int index = states.indexOf(newSetState);
					tmp_state.getTransitions().add(new TransitionDFA(states.get(index), transitions.get(j)));
				}
				else
				{
					states.add(newSetState);
					tmp_state.getTransitions().add(new TransitionDFA(newSetState, transitions.get(j)));
				}
			}
			
		}
		
	}
	public void createVisualization(){
		visualizer = new AutomataVisualizer();
		initialState.visited = true;

		Queue<SetState> states = new LinkedList<SetState>();
		states.add(initialState);
		initialState.vertexNo = visualizer.addVertex();
	 
		if(initialState.isFinal())
			AutomataVisualizer.final_vertex.add(String.valueOf(initialState.vertexNo));
		while(!states.isEmpty()){
			SetState temp = states.poll();
			for(int i = 0; i < temp.getTransitions().size(); i++){
				TransitionDFA trans = temp.getTransitions().get(i);
				if(!trans.visited){
					trans.visited = true;
					SetState dest = trans.getDestinationState();

					if(!dest.visited){
						states.add(dest);
						dest.vertexNo = visualizer.addVertex();
						if(dest.isFinal())
							AutomataVisualizer.final_vertex.add(String.valueOf(dest.vertexNo));
						dest.visited = true;
					}
					visualizer.addEdge(trans.getValue(), temp.vertexNo, dest.vertexNo);
				}
			}
		}

		visualizer.view(1024, 700);

	}
}
